package euler.helper;


public class SistemasEcuaciones {
    
    public static Rational[] resolverGaussiana(long[][] matrixL, long[] ind) {
        
        Rational[][] matrix = convert(matrixL);
        Rational[] solution = convert(ind);
        
        for (int i = 0; i < matrix.length; i++) {
            if (matrix[i][i].getNum() != 1 || matrix[i][i].getDenum() != 1) {
                Rational inverso = matrix[i][i].inverso();
                
                for (int j = 0; j < matrix[i].length; j++) {
                    matrix[i][j] = matrix[i][j].producto(inverso);
                }
                
                solution[i] = solution[i].producto(inverso);
            }
            
            for (int j = i+1; j < solution.length; j++) {
                Rational coe = matrix[j][i].negado();
                for (int k = 0; k < solution.length; k++) {
                    matrix[j][k] = matrix[j][k].suma(matrix[i][k].producto(coe));
                }
                
                solution[j] = solution[j].suma(solution[i].producto(coe));
            }
        }
        
        for (int i = matrix.length - 1; i >= 0; i--) {
            for (int j = i-1; j >= 0; j--) {
                solution[j] = solution[j].resta(solution[i].producto(matrix[j][i]));
                matrix[j][i] = Rational.ZERO;
            }
        }
        
        return solution;
    }
    
    private static Rational[] convert(long[] in) {
        Rational[] out = new Rational[in.length];
        
        for (int i = 0; i < in.length; i++) {
            out[i] = new Rational(in[i], 1l);
        }
        
        return out;
    }
    
    private static Rational[][] convert(long[][] in) {
        Rational[][] out = new Rational[in.length][];
        
        for (int i = 0; i < in.length; i++) {
            out[i] = convert(in[i]);
        }
        
        return out;
    }
}
